package com.dxl.web.common.controller;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.dxl.common.annotation.RequirePermission;
import com.dxl.common.id.UUIDGenerator;
import com.dxl.common.model.RespData;
import com.dxl.common.utils.DateUtils;
import com.dxl.common.utils.FileUtils;
import com.dxl.common.utils.Utils;
import com.dxl.lanju.service.OssManager;

import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.Thumbnails.Builder;

/**
 * Oss文件上传控制器
 * @author 邓小林
 */
@Controller
@RequirePermission(value={"OSS-MODULE"}, name="OSS模块", desc="包括所有文件上传至OSS")
public class OssController extends BaseController {
	private static final Logger LOG = Logger.getLogger(OssController.class);
	
	@ResponseBody
	@RequestMapping(value = "/ossupload", method=RequestMethod.POST)
	@RequirePermission(value={"OSS-UPLOAD"}, name="OSS文件上传", desc="通用OSS文件上传")
	public RespData ossupload(HttpServletRequest req, String size) {
		if (!ServletFileUpload.isMultipartContent(req)) {
			return RespData.instance(RespData.FAIL, "请选择要上传的文件");
		}
		Map<String, MultipartFile> fileMap = ((MultipartHttpServletRequest) req).getFileMap();
		if (Utils.isNull(fileMap) || fileMap.isEmpty()) {
			return RespData.instance(RespData.FAIL, "请选择要上传文件");
		}
		Iterator<MultipartFile> it = fileMap.values().iterator();
		MultipartFile mFile;
		String errorMsg = "", uri;
		Set<String> uris = new LinkedHashSet<String>();
		while (it.hasNext()) {
			mFile = it.next();
			try {
				uri = getUri(mFile);
				OssManager.upload(uri, Utils.isBlank(size) ? mFile.getBytes() : resize(mFile, size));
				uris.add(uri);
			} catch (Exception e) {
				LOG.error(e.getMessage(), e);
				if (Utils.isBlank(errorMsg)) {
					errorMsg += ",";
				}
				errorMsg += mFile.getOriginalFilename();
			}
		}
		if (Utils.isNotBlank(errorMsg)) {
			return RespData.instance(RespData.SUCCESS, errorMsg + "上传失败");
		}
		return RespData.instance(RespData.SUCCESS, "上传成功", uris.size() > 1 ? uris.iterator().next() : uris);
	}
	
	private byte[] resize(MultipartFile mFile, String size) {
		Integer width = null, height = null;
		if (Utils.isNotBlank(size)) {
			String[] tmp = size.split("\\*");
			if (Utils.isNotEmpty(tmp) && tmp.length == 2) {
				width = Utils.toInt(tmp[0]);
				height = Utils.toInt(tmp[1]);
			}
		}
		if (Utils.isNull(mFile) || Utils.isNull(width) || Utils.isNull(height)) {
			return null;
		}
		InputStream in = null;
		ByteArrayOutputStream out = null;
		try {
			in = mFile.getInputStream();
			BufferedImage image = ImageIO.read(in);  
			Builder<BufferedImage> builder;  
//			int imgWidth = image.getWidth();  
//			int imgHeitht = image.getHeight();  
//			if ((float)height / width != (float)imgWidth / imgHeitht) {  
//			    if (imgWidth > imgHeitht) {  
//			        image = Thumbnails.of(image).height(height).asBufferedImage();  
//			    } else {
//			        image = Thumbnails.of(image).width(width).asBufferedImage();  
//			    }  
//			    builder = Thumbnails.of(image).sourceRegion(Positions.CENTER, width, height).size(width, height);  
//			} else {
			    builder = Thumbnails.of(image).size(width, height);  
//			}  
			out = new ByteArrayOutputStream();
			builder.outputQuality(0.50f).outputFormat(FileUtils.fileSuffix(mFile.getOriginalFilename())).toOutputStream(out); 
			return out.toByteArray();
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
		} finally {
			if (Utils.isNotNull(in)) {
				try {
					in.close();
				} catch (Exception e) {
					LOG.error(e.getMessage(), e);
				}
			}
			if (Utils.isNotNull(out)) {
				try {
					out.close();
				} catch (Exception e) {
					LOG.error(e.getMessage(), e);
				}
			}
		}
		return null;
	}
	
	private static String getUri(MultipartFile mFile) {
		String path = "uploaded/" + DateUtils.formatDate(new Date(), DateUtils.DF_yyyyMMdd) + "/" + UUIDGenerator.get().genUUID().replace("-", "") + "." + FileUtils.fileSuffix(mFile.getOriginalFilename());
		return path;
	}
}
